interface EnumItem {
  label: string;
  [key: string]: any;
}

type Enum = Record<string, EnumItem>;

interface Config {
  labelField: string;
  valueField: string;
}
interface EnumOptions {
  _options: { [key: string]: any }[];
}

export const createEnum = <E extends Enum>(
  e: E,
  config: Config = {
    labelField: 'label',
    valueField: 'value',
  },
): EnumOptions & {
  [K in keyof E]: { [V in keyof E[K]]: any } & { value: K };
} => {
  const { labelField, valueField } = config;
  const result = { _options: [] } as any;

  Object.keys(e).forEach((key) => {
    if (key === '_options') {
      throw new Error('"_options" cannot be used as an enum key.');
    }
    const item = e[key as keyof E];
    result[key] = { ...item, value: item?.value ?? key };
    result._options.push({
      [labelField]: item.label ?? key,
      [valueField]: item?.value ?? key,
    });
  });

  return result;
};
